home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / NEWAVE / NEWAVE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  23.4 KB  |  890 lines

  1. /* 
  2.  
  3.  Newave - Ported from the original IrisGL SGI demo 
  4.           (see https://www.sgi.com/toolbox/src/)
  5.  
  6.  I've ported an old IrisGL demo, newave, to OpenGL and GLUT.  
  7.  This port has a couple of new features compared to the 
  8.  "ancient" GL demo:
  9.  
  10.      * environment mapping (very cool!)
  11.      * texture mapping
  12.      * line antialiasing (needs some work)
  13.      * better wave propagation
  14.  
  15.  I haven't implemented the mesh editing found in the old demo. 
  16.  
  17.  By default the program loads "texmap.rgb" and "spheremap.rgb"
  18.  if no filenames are given as command line arguments.  
  19.  Specify the texture map as the first argument and the sphere
  20.  map as the second argument.
  21.  
  22.  Left mouse rotates the scene, middle mouse or +/- keys zoom, 
  23.  right mouse for menu.
  24.  
  25.  Erik Larsen
  26.  cayman@sprintmail.com
  27.  
  28. */
  29.  
  30. #include <math.h>
  31. #include <stdlib.h>
  32. #include <GL/glut.h>
  33. #include "texture.h"
  34.  
  35. #if defined(GL_EXT_texture_object) && !defined(GL_VERSION_1_1)
  36. #define glBindTexture(A,B)     glBindTextureEXT(A,B)
  37. #define glGenTextures(A,B)     glGenTexturesEXT(A,B)
  38. #endif
  39. #if defined(GL_EXT_polygon_offset) && !defined(GL_VERSION_1_1)
  40. #define glPolygonOffset(A,B)     glPolygonOffsetEXT(A,B)
  41. /* OpenGL 1.1's polygon offset can be different for each
  42.    polygon mode primitive type.  The EXT extension has
  43.    only one offset. */
  44. #define GL_POLYGON_OFFSET_FILL   GL_POLYGON_OFFSET_EXT
  45. #endif
  46.  
  47. typedef int bool;
  48. #define true 1
  49. #define false 0
  50.  
  51. /* Grid */
  52. #define MAXGRID 63
  53. enum {WIREFRAME, HIDDENLINE, FLATSHADED, SMOOTHSHADED, TEXTURED};
  54. enum {FULLSCREEN, FACENORMALS, ANTIALIAS, ENVMAP};
  55. enum {WEAK, NORMAL, STRONG};
  56. enum {SMALL, MEDIUM, LARGE, XLARGE};
  57. enum {CURRENT, FLAT, SPIKE, DIAGONALWALL, SIDEWALL, HOLE, 
  58.       MIDDLEBLOCK, DIAGONALBLOCK, CORNERBLOCK, HILL, HILLFOUR};
  59. int displayMode = WIREFRAME;
  60. int resetMode = DIAGONALBLOCK;
  61. int grid = 17;
  62. float dt = 0.004;
  63. float force[MAXGRID][MAXGRID],
  64.       veloc[MAXGRID][MAXGRID],
  65.       posit[MAXGRID][MAXGRID],
  66.       vertNorms[MAXGRID][MAXGRID][3],
  67.       faceNorms[2][MAXGRID][MAXGRID][3],
  68.       faceNormSegs[2][2][MAXGRID][MAXGRID][3];
  69. bool waving = false, editing = false, 
  70.      drawFaceNorms = false, antialias = false,
  71.      envMap = false;
  72. #define SQRTOFTWOINV 1.0 / 1.414213562
  73.  
  74. /* Some <math.h> files do not define M_PI... */
  75. #ifndef M_PI
  76. #define M_PI 3.14159265358979323846
  77. #endif
  78.  
  79. int texWidth, texHeight;
  80. GLubyte *texData;
  81. char *texFilename1 = "texmap.rgb", *texFilename2 = "spheremap.rgb";
  82. GLuint texId1, texId2;
  83. float texCoords[MAXGRID][MAXGRID][2];
  84.  
  85. /* Viewing */
  86. float sphi=90.0, stheta=45.0;
  87. float sdepth = 5.0/4.0 * MAXGRID;
  88. float zNear=15.0, zFar=100.0;
  89. float aspect = 5.0/4.0;
  90. long xsize, ysize;
  91. int downX, downY;
  92. bool leftButton = false, middleButton = false;
  93. int i,j;
  94. GLfloat lightPosition[] = { 0.0, 0.0, 1.0, 1.0}; 
  95. int displayMenu, otherMenu, speedMenu, sizeMenu, 
  96.     resetMenu, mainMenu;
  97.  
  98. void getforce(void)
  99. {
  100.     float d;
  101.  
  102.     for(i=0;i<grid;i++) 
  103.         for(j=0;j<grid;j++) 
  104.         {
  105.             force[i][j]=0.0;
  106.         }
  107.  
  108.     for(i=2;i<grid-2;i++)
  109.         for(j=2;j<grid-2;j++) 
  110.         {
  111.             d=posit[i][j]-posit[i][j-1];
  112.             force[i][j] -= d;
  113.             force[i][j-1] += d;
  114.  
  115.             d=posit[i][j]-posit[i-1][j];
  116.             force[i][j] -= d;
  117.             force[i-1][j] += d;
  118.  
  119.             d= (posit[i][j]-posit[i][j+1]); 
  120.             force[i][j] -= d ;
  121.             force[i][j+1] += d;
  122.  
  123.             d= (posit[i][j]-posit[i+1][j]); 
  124.             force[i][j] -= d ;
  125.             force[i+1][j] += d;
  126.  
  127.             d= (posit[i][j]-posit[i+1][j+1])*SQRTOFTWOINV; 
  128.             force[i][j] -= d ;
  129.             force[i+1][j+1] += d;
  130.  
  131.             d= (posit[i][j]-posit[i-1][j-1])*SQRTOFTWOINV; 
  132.             force[i][j] -= d ;
  133.             force[i-1][j-1] += d;
  134.  
  135.             d= (posit[i][j]-posit[i+1][j-1])*SQRTOFTWOINV; 
  136.             force[i][j] -= d ;
  137.             force[i+1][j-1] += d;
  138.  
  139.             d= (posit[i][j]-posit[i-1][j+1])*SQRTOFTWOINV; 
  140.             force[i][j] -= d ;
  141.             force[i- 1][j+1] += d;
  142.         }
  143. }
  144.  
  145. void getvelocity(void)
  146. {
  147.     for(i=0;i<grid;i++)
  148.         for(j=0;j<grid;j++)
  149.             veloc[i][j]+=force[i][j] * dt;
  150. }
  151.  
  152. void getposition(void)
  153. {
  154.     for(i=0;i<grid;i++)
  155.         for(j=0;j<grid;j++)
  156.             posit[i][j]+=veloc[i][j];
  157. }
  158.  
  159.  
  160. void copy(float vec0[3], float vec1[3])
  161. {
  162.     vec0[0] = vec1[0];
  163.     vec0[1] = vec1[1];
  164.     vec0[2] = vec1[2];
  165. }
  166.  
  167. void sub(float vec0[3], float vec1[3], float vec2[3])
  168. {
  169.     vec0[0] = vec1[0] - vec2[0];
  170.     vec0[1] = vec1[1] - vec2[1];
  171.     vec0[2] = vec1[2] - vec2[2];
  172. }
  173.  
  174. void add(float vec0[3], float vec1[3], float vec2[3])
  175. {
  176.     vec0[0] = vec1[0] + vec2[0];
  177.     vec0[1] = vec1[1] + vec2[1];
  178.     vec0[2] = vec1[2] + vec2[2];
  179. }
  180.  
  181. void scalDiv(float vec[3], float c)
  182. {
  183.     vec[0] /= c; vec[1] /= c; vec[2] /= c;
  184. }
  185.  
  186. void cross(float vec0[3], float vec1[3], float vec2[3])
  187. {
  188.     vec0[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
  189.     vec0[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
  190.     vec0[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
  191. }
  192.  
  193. void norm(float vec[3])
  194. {
  195.     float c = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
  196.     scalDiv(vec, c); 
  197. }
  198.  
  199. void set(float vec[3], float x, float y, float z)
  200. {
  201.     vec[0] = x;
  202.     vec[1] = y;
  203.     vec[2] = z;
  204. }
  205.  
  206.  
  207. /* face normals - for flat shading */
  208. void getFaceNorms(void)
  209. {
  210.     float vec0[3], vec1[3], vec2[3], norm0[3], norm1[3];
  211.     float geom0[3], geom1[3], geom2[3], geom3[3];
  212.     for (i = 0; i < grid-1; ++i)
  213.     {
  214.         for (j = 0; j < grid-1; ++j)
  215.         {
  216.             /* get vectors from geometry points */
  217.             geom0[0] = i; geom0[1] = j; geom0[2] = posit[i][j];
  218.             geom1[0] = i; geom1[1] = j+1; geom1[2] = posit[i][j+1];
  219.             geom2[0] = i+1; geom2[1] = j; geom2[2] = posit[i+1][j];
  220.             geom3[0] = i+1; geom3[1] = j+1; geom3[2] = posit[i+1][j+1];
  221.  
  222.             sub( vec0, geom1, geom0 );
  223.             sub( vec1, geom1, geom2 );
  224.             sub( vec2, geom1, geom3 );
  225.  
  226.             /* get triangle face normals from vectors & normalize them */
  227.             cross( norm0, vec0, vec1 );
  228.             norm( norm0 );
  229.  
  230.             cross( norm1, vec1, vec2 ); 
  231.             norm( norm1 );
  232.  
  233.             copy( faceNorms[0][i][j], norm0 );
  234.             copy( faceNorms[1][i][j], norm1 );
  235.         }
  236.     }
  237. }
  238.  
  239. /* vertex normals - average of face normals for smooth shading */
  240. void getVertNorms(void)
  241. {
  242.     float avg[3];
  243.     for (i = 0; i < grid; ++i)
  244.     {
  245.         for (j = 0; j < grid; ++j)
  246.         {
  247.             /* For each vertex, average normals from all faces sharing */
  248.             /* vertex.  Check each quadrant in turn */
  249.             set(avg, 0.0, 0.0, 0.0);
  250.  
  251.             /* Right & above */
  252.             if (j < grid-1 && i < grid-1)
  253.             {
  254.                 add( avg, avg, faceNorms[0][i][j] );
  255.             }
  256.             /* Right & below */
  257.             if (j < grid-1 && i > 0)
  258.             {
  259.                 add( avg, avg, faceNorms[0][i-1][j] );
  260.                 add( avg, avg, faceNorms[1][i-1][j] );
  261.             }
  262.             /* Left & above */
  263.             if (j > 0 && i < grid-1)
  264.             {
  265.                 add( avg, avg, faceNorms[0][i][j-1] );
  266.                 add( avg, avg, faceNorms[1][i][j-1] );
  267.             }
  268.             /* Left & below */
  269.             if (j > 0 && i > 0)
  270.             {
  271.                 add( avg, avg, faceNorms[1][i-1][j-1] );
  272.             }
  273.  
  274.             /* Normalize */
  275.             norm( avg );
  276.             copy( vertNorms[i][j], avg );
  277.         }
  278.     }
  279. }
  280.  
  281.  
  282. void getFaceNormSegs(void)
  283. {
  284.     float center0[3], center1[3], normSeg0[3], normSeg1[3];
  285.     float geom0[3], geom1[3], geom2[3], geom3[3];
  286.     for (i = 0; i < grid - 1; ++i)
  287.     {
  288.         for (j = 0; j < grid - 1; ++j)
  289.         {
  290.             geom0[0] = i; geom0[1] = j; geom0[2] = posit[i][j];
  291.             geom1[0] = i; geom1[1] = j+1; geom1[2] = posit[i][j+1];
  292.             geom2[0] = i+1; geom2[1] = j; geom2[2] = posit[i+1][j];
  293.             geom3[0] = i+1; geom3[1] = j+1; geom3[2] = posit[i+1][j+1];
  294.  
  295.             /* find center of triangle face by averaging three vertices */
  296.             add( center0, geom2, geom0 );
  297.             add( center0, center0, geom1 );
  298.             scalDiv( center0, 3.0 );
  299.  
  300.             add( center1, geom2, geom1 );
  301.             add( center1, center1, geom3 );
  302.             scalDiv( center1, 3.0 );
  303.  
  304.             /* translate normal to center of triangle face to get normal segment */
  305.             add( normSeg0, center0, faceNorms[0][i][j] );
  306.             add( normSeg1, center1, faceNorms[1][i][j] );
  307.  
  308.             copy( faceNormSegs[0][0][i][j], center0 );
  309.             copy( faceNormSegs[1][0][i][j], center1 );
  310.  
  311.             copy( faceNormSegs[0][1][i][j], normSeg0 );
  312.             copy( faceNormSegs[1][1][i][j], normSeg1 );
  313.         }
  314.     }
  315. }
  316.  
  317. void getTexCoords(void)
  318. {
  319.     for (i = 0; i < grid; ++i)
  320.     {
  321.         for (j = 0; j < grid; ++j)
  322.         {
  323.             texCoords[i][j][0] = (float)j/(float)(grid-1);
  324.             texCoords[i][j][1] = (float)i/(float)(grid-1);
  325.         }
  326.     }
  327. }
  328.  
  329.  
  330. void wave(void)
  331. {
  332.     if (waving)
  333.     {
  334.         getforce();
  335.         getvelocity();
  336.         getposition();
  337.         glutPostRedisplay();
  338.     }
  339. }
  340.  
  341. void go(void)
  342. {
  343.     waving = true;
  344.     editing = false;
  345.     glutIdleFunc(wave);
  346. }
  347.  
  348. void stop(void)
  349. {
  350.     waving = false;
  351.     glutIdleFunc(NULL);
  352. }
  353.  
  354. void edit(void)
  355. {
  356.     stop();
  357.     editing = true;
  358. }
  359.  
  360. void reverse(void)
  361. {
  362.     for(i=1;i<(grid-1);i++)
  363.         for(j=1;j<(grid-1);j++)
  364.             veloc[i][j]= -veloc[i][j];
  365.  
  366.     if (!waving)
  367.         go();
  368. }
  369.  
  370. void reset(int value)
  371. {
  372.     if (waving)
  373.         stop();
  374.  
  375.     if (value != CURRENT)
  376.         resetMode = value;
  377.     for(i=0;i<grid;i++)
  378.         for(j=0;j<grid;j++)
  379.         {
  380.             force[i][j]=0.0;
  381.             veloc[i][j]=0.0;
  382.  
  383.             switch(resetMode)
  384.             {
  385.             case FLAT:
  386.                 posit[i][j] = 0.0;
  387.                 break;
  388.             case SPIKE:
  389.                  posit[i][j]= (i==j && i == grid/2) ? grid*1.5 : 0.0;
  390.                 break;
  391.             case HOLE:
  392.                 posit[i][j]= (!((i > grid/3 && j > grid/3)&&(i < grid*2/3 && j < grid*2/3))) ? grid/4 : 0.0;
  393.                 break;
  394.             case DIAGONALWALL:
  395.                 posit[i][j]= (((grid-i)-j<3) && ((grid-i)-j>0)) ? grid/6 : 0.0;
  396.                 break;
  397.             case SIDEWALL:
  398.                 posit[i][j]= (i==1) ? grid/4 : 0.0;
  399.                 break;
  400.             case DIAGONALBLOCK:
  401.                 posit[i][j]= ((grid-i)-j<3) ? grid/6 : 0.0;
  402.                 break;
  403.             case MIDDLEBLOCK:
  404.                 posit[i][j]= ((i > grid/3 && j > grid/3)&&(i < grid*2/3 && j < grid*2/3)) ? grid/4 : 0.0;
  405.                 break;
  406.             case CORNERBLOCK:
  407.                 posit[i][j]= ((i > grid*3/4 && j > grid*3/4)) ? grid/4 : 0.0;
  408.                 break;
  409.             case HILL:
  410.                 posit[i][j]= 
  411.                     (sin(M_PI * ((float)i/(float)grid)) +
  412.                      sin(M_PI * ((float)j/(float)grid)))* grid/6.0;
  413.             break;        
  414.             case HILLFOUR:
  415.                 posit[i][j]= 
  416.                     (sin(M_PI*2 * ((float)i/(float)grid)) +
  417.                      sin(M_PI*2 * ((float)j/(float)grid)))* grid/6.0;
  418.             break;        
  419.             }
  420.             if (i==0||j==0||i==grid-1||j==grid-1) posit[i][j]=0.0;
  421.         }
  422.     glutPostRedisplay();
  423. }
  424.  
  425. void setSize(int value)
  426. {
  427.     int prevGrid = grid;
  428.     switch(value) 
  429.     {
  430.         case SMALL : grid = MAXGRID/4; break;
  431.         case MEDIUM: grid = MAXGRID/2; break;
  432.         case LARGE : grid = MAXGRID/1.5; break;
  433.         case XLARGE : grid = MAXGRID; break;
  434.     }
  435.     if (prevGrid > grid)
  436.     {
  437.         reset(resetMode);
  438.     }
  439.     zNear= grid/10.0;
  440.     zFar= grid*3.0;
  441.     sdepth = 5.0/4.0 * grid;
  442.     getTexCoords();
  443.     glutPostRedisplay();
  444. }
  445.  
  446. void setSpeed(int value)
  447. {
  448.     switch(value) 
  449.     {
  450.         case WEAK  : dt = 0.001; break;
  451.         case NORMAL: dt = 0.004; break;
  452.         case STRONG: dt = 0.008; break;
  453.     }
  454. }
  455.  
  456. void setDisplay(int value)
  457. {
  458.     displayMode = value;
  459.     switch(value) 
  460.     {
  461.         case WIREFRAME   : 
  462.             glShadeModel(GL_FLAT); 
  463.             glDisable(GL_LIGHTING);
  464.             break;
  465.         case HIDDENLINE: 
  466.             glShadeModel(GL_FLAT); 
  467.             glDisable(GL_LIGHTING);
  468.             break;
  469.         case FLATSHADED  : 
  470.             glShadeModel(GL_FLAT); 
  471.             glEnable(GL_LIGHTING);
  472.             break;
  473.         case SMOOTHSHADED: 
  474.             glShadeModel(GL_SMOOTH); 
  475.             glEnable(GL_LIGHTING);
  476.             break;
  477.         case TEXTURED: 
  478.             glShadeModel(GL_SMOOTH); 
  479.             glEnable(GL_LIGHTING);
  480.             break;
  481.     }
  482.     glutPostRedisplay();
  483. }
  484.  
  485. void setOther(int value)
  486. {
  487.     switch (value)
  488.     {
  489.         case FULLSCREEN: 
  490.             glutFullScreen();
  491.             break;
  492.         case FACENORMALS: 
  493.             drawFaceNorms = !drawFaceNorms;
  494.             break;
  495.         case ANTIALIAS: 
  496.             antialias = !antialias;
  497.             if (antialias)
  498.             {
  499.                 glEnable(GL_BLEND);
  500.                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  501.                 glEnable(GL_LINE_SMOOTH);
  502.                 glLineWidth(1.5);
  503.             }
  504.             else
  505.             {
  506.                 glDisable(GL_BLEND);
  507.                 glDisable(GL_LINE_SMOOTH);
  508.                 glLineWidth(1.0);
  509.             }
  510.             break;
  511.         case ENVMAP: 
  512.             envMap = !envMap;
  513.             if (envMap)
  514.             {
  515.                 glBindTexture(GL_TEXTURE_2D, texId2);
  516.                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  517.                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  518.                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  519.                 glEnable(GL_TEXTURE_GEN_S);
  520.                 glEnable(GL_TEXTURE_GEN_T);
  521.             }
  522.             else
  523.             {
  524.                 glBindTexture(GL_TEXTURE_2D, texId1);
  525.                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  526.                 glDisable(GL_TEXTURE_GEN_S);
  527.                 glDisable(GL_TEXTURE_GEN_T);
  528.             }
  529.             break;
  530.     }
  531.     glutPostRedisplay();
  532. }
  533.  
  534. void setMain(int value)
  535. {
  536.     switch(value) 
  537.     {
  538.         case 1: edit();    break;
  539.         case 2:    go();      break; /* set idle func to something */
  540.         case 3: stop();    break; /* set idle func to null */
  541.         case 4:    reverse(); break;
  542.         case 5:    exit(0);   break;
  543.     }
  544. }
  545.  
  546.  
  547. void drawFaceNormals(void)
  548. {
  549.     glColor3f(1.0,1.0,1.0);
  550.     for (i = 0; i < grid - 1; ++i)
  551.     {
  552.         for (j = 0; j < grid - 1; ++j)
  553.         {
  554.             glBegin(GL_LINES);
  555.             glVertex3fv(faceNormSegs[0][0][i][j]);
  556.             glVertex3fv(faceNormSegs[0][1][i][j]);
  557.             glEnd();
  558.  
  559.             glBegin(GL_LINES);
  560.             glVertex3fv(faceNormSegs[1][0][i][j]);
  561.             glVertex3fv(faceNormSegs[1][1][i][j]);
  562.             glEnd();
  563.         }
  564.     }
  565. }
  566.  
  567. void drawSmoothShaded(void)
  568. {
  569.     glColor3f(0.8f, 0.2f, 0.8f);
  570.     for (i = 0; i < grid - 1; ++i)
  571.     {
  572.         glBegin(GL_TRIANGLE_STRIP);
  573.         for (j = 0; j < grid; ++j)
  574.         {
  575.             glNormal3fv( vertNorms[i][j] );
  576.             glVertex3f( i, j, posit[i][j] );
  577.             glNormal3fv( vertNorms[i+1][j] );
  578.             glVertex3f( i+1, j, posit[i+1][j] );
  579.         }
  580.         glEnd();
  581.     }
  582. }
  583.  
  584. void drawWireframe(void)
  585. {
  586.     glColor3f(1.0, 1.0, 1.0);
  587.  
  588.     for(i=0;i<grid;i++)
  589.     {
  590.         glBegin(GL_LINE_STRIP);
  591.         for(j=0;j<grid;j++)
  592.             glVertex3f( (float) i, (float) j, (float) posit[i][j]);
  593.         glEnd();
  594.     }
  595.     
  596.     for(i=0;i<grid;i++)
  597.     {
  598.         glBegin(GL_LINE_STRIP);
  599.         for(j=0;j<grid;j++)
  600.             glVertex3f( (float) j, (float) i, (float) posit[j][i]);
  601.         glEnd();
  602.     }
  603. }
  604.  
  605. void drawFlatShaded(void)
  606. {
  607.     glEnable(GL_POLYGON_OFFSET_FILL);
  608.     glColor3f(0.8f, 0.2f, 0.8f);
  609.     for (i = 0; i < grid - 1; ++i)
  610.     {
  611.         glBegin(GL_TRIANGLE_STRIP);
  612.         glVertex3f( (float) i, (float) 0, (float) posit[i][0]);
  613.         glVertex3f( (float) i+1, (float) 0, (float) posit[i+1][0]);
  614.         for (j = 1; j < grid; ++j)
  615.         {
  616.             glNormal3fv( faceNorms[0][i][j-1] );
  617.             glVertex3f( (float) i, (float) j, (float) posit[i][j]);
  618.               glNormal3fv( faceNorms[1][i][j-1] );
  619.             glVertex3f( (float) i+1, (float) j, (float) posit[i+1][j]);
  620.         }
  621.         glEnd();
  622.     }
  623.     glDisable(GL_POLYGON_OFFSET_FILL);
  624. }
  625.  
  626. void drawHiddenLine(void)
  627. {
  628.     glEnable(GL_POLYGON_OFFSET_FILL);
  629.     glColor3f(0.8f, 0.2f, 0.8f);
  630.     for (i = 0; i < grid - 1; ++i)
  631.     {
  632.         glBegin(GL_TRIANGLE_STRIP);
  633.         glVertex3f( (float) i, (float) 0, (float) posit[i][0]);
  634.         glVertex3f( (float) i+1, (float) 0, (float) posit[i+1][0]);
  635.         for (j = 1; j < grid; ++j)
  636.         {
  637.             glVertex3f( (float) i, (float) j, (float) posit[i][j]);
  638.             glVertex3f( (float) i+1, (float) j, (float) posit[i+1][j]);
  639.         }
  640.         glEnd();
  641.     }    
  642.     glDisable(GL_POLYGON_OFFSET_FILL);
  643.     
  644.     glColor3f(1.0,1.0,1.0);
  645.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  646.     for (i = 0; i < grid - 1; ++i)
  647.     {
  648.         glBegin(GL_TRIANGLE_STRIP);
  649.         glVertex3f( (float) i, (float) 0, (float) posit[i][0]);
  650.         glVertex3f( (float) i+1, (float) 0, (float) posit[i+1][0]);
  651.         for (j = 1; j < grid; ++j)
  652.         {
  653.             glVertex3f( (float) i, (float) j, (float) posit[i][j]);
  654.             glVertex3f( (float) i+1, (float) j, (float) posit[i+1][j]);
  655.         }
  656.         glEnd();
  657.     }    
  658.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  659. }
  660.  
  661. void loadImageTexture(void)
  662. {
  663.  
  664.     glGenTextures(1,&texId1);
  665.     glBindTexture(GL_TEXTURE_2D, texId1);
  666.     imgLoad(texFilename1, 0, 0, &texWidth, &texHeight, &texData);
  667.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  668.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  669.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  670.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  671.     glTexImage2D(GL_TEXTURE_2D, 0, 4, 
  672.         texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  673.         texData );
  674.  
  675.     glGenTextures(1,&texId2);
  676.     glBindTexture(GL_TEXTURE_2D, texId2);
  677.     imgLoad(texFilename2, 0, 0, &texWidth, &texHeight, &texData);
  678.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  679.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  680.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  681.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  682.     glTexImage2D(GL_TEXTURE_2D, 0, 4, 
  683.         texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
  684.         texData );
  685. }
  686.  
  687. void drawTextured(void)
  688. {
  689.     glColor3f(1.0f, 1.0f, 1.0f);
  690.     glEnable(GL_TEXTURE_2D);
  691.     for (i = 0; i < grid - 1; ++i)
  692.     {
  693.         glBegin(GL_TRIANGLE_STRIP);
  694.         for (j = 0; j < grid; ++j)
  695.         {
  696.             glNormal3fv( vertNorms[i][j] );
  697.             glTexCoord2fv( texCoords[i][j] );
  698.             glVertex3f( i, j, posit[i][j] );
  699.             glNormal3fv( vertNorms[i+1][j] );
  700.             glTexCoord2fv( texCoords[i+1][j] );
  701.             glVertex3f( i+1, j, posit[i+1][j] );
  702.         }
  703.         glEnd();
  704.     }
  705.     glDisable(GL_TEXTURE_2D);
  706. }
  707.  
  708.  
  709. void reshape(int width, int height)
  710. {
  711.     xsize = width; 
  712.     ysize = height;
  713.     aspect = (float)xsize/(float)ysize;
  714.     glViewport(0, 0, xsize, ysize);
  715.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  716.     glutPostRedisplay();
  717. }
  718.  
  719. void display(void) 
  720. {
  721.     glMatrixMode(GL_PROJECTION);
  722.     glLoadIdentity();
  723.     gluPerspective(64.0, aspect, zNear, zFar);
  724.     glMatrixMode(GL_MODELVIEW);
  725.     glLoadIdentity(); 
  726.  
  727.     glTranslatef(0.0,0.0,-sdepth);
  728.     glRotatef(-stheta, 1.0, 0.0, 0.0);
  729.     glRotatef(sphi, 0.0, 0.0, 1.0);
  730.     glTranslatef(-(float)((grid+1)/2-1), -(float)((grid+1)/2-1), 0.0);
  731.  
  732.       getFaceNorms();
  733.     getVertNorms();
  734.  
  735.     switch (displayMode) 
  736.     {
  737.         case WIREFRAME: drawWireframe(); break;
  738.         case HIDDENLINE: drawHiddenLine(); break;
  739.         case FLATSHADED: drawFlatShaded(); break;
  740.         case SMOOTHSHADED: drawSmoothShaded(); break;
  741.         case TEXTURED: drawTextured(); break;
  742.     }
  743.  
  744.     if (drawFaceNorms)    
  745.     {
  746.         getFaceNormSegs();
  747.         drawFaceNormals();
  748.     }
  749.  
  750.     glutSwapBuffers();
  751.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  752. }
  753.  
  754. void visibility(int state)
  755. {
  756.     if ((state == GLUT_VISIBLE) && waving)
  757.         go();
  758.     else 
  759.         stop();
  760. }
  761.  
  762. void motion(int x, int y)
  763. {
  764.     if (leftButton)
  765.     {
  766.         sphi += (float)(x - downX) / 4.0;
  767.         stheta += (float)(downY - y) / 4.0;
  768.     }
  769.     if (middleButton)
  770.     {
  771.         sdepth += (float)(downY - y) / 10.0;
  772.     }
  773.     downX = x;
  774.     downY = y;
  775.     glutPostRedisplay();
  776. }
  777.  
  778.  
  779. void mouse(int button, int state, int x, int y)
  780. {
  781.     downX = x;
  782.     downY = y;
  783.     leftButton = ((button == GLUT_LEFT_BUTTON) && 
  784.                   (state == GLUT_DOWN));
  785.     middleButton = ((button == GLUT_MIDDLE_BUTTON) && 
  786.                     (state == GLUT_DOWN));
  787. }
  788.  
  789. void keyboard(unsigned char ch, int x, int y)
  790. {
  791.     switch (ch) 
  792.     {
  793.         case '+': sdepth += 2.0; break;
  794.         case '-': sdepth -= 2.0; break;
  795.         case 27: exit(0); break;
  796.     }
  797.     glutPostRedisplay();
  798. }
  799.  
  800. void main(int argc, char **argv)
  801. {
  802.     glutInit(&argc, argv);
  803.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  804.     glutInitWindowSize(500, 500);
  805.     glutCreateWindow("Newave");
  806.     if (argc > 1 && argv[1] != 0)
  807.         texFilename1 = argv[1];
  808.     if (argc > 2 && argv[2] != 0)
  809.         texFilename2 = argv[2];
  810.     glEnable(GL_DEPTH_TEST);
  811.     glDepthFunc(GL_LEQUAL);
  812.     glClearColor(0.0, 0.0, 0.0, 0.0);
  813.     glPolygonOffset(1.0, 1.0);
  814.     glEnable(GL_CULL_FACE);
  815.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  816.     glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  817.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  818.     glEnable(GL_COLOR_MATERIAL);
  819.     glColorMaterial(GL_FRONT, GL_DIFFUSE);
  820.     glLightfv (GL_LIGHT0, GL_POSITION, lightPosition);
  821.     glEnable(GL_LIGHT0);
  822.     loadImageTexture();
  823.  
  824.     setSize(MEDIUM);
  825.     setSpeed(NORMAL);
  826.     setDisplay(TEXTURED);
  827.     setOther(ENVMAP);
  828.     reset(HILLFOUR);
  829.  
  830.     glutReshapeFunc(reshape);
  831.     glutDisplayFunc(display);
  832.     glutVisibilityFunc(visibility);
  833.  
  834.     glutKeyboardFunc(keyboard);
  835.     glutMouseFunc(mouse);
  836.     glutMotionFunc(motion);
  837.  
  838.     displayMenu = glutCreateMenu(setDisplay);
  839.     glutAddMenuEntry("Wireframe", WIREFRAME);
  840.     glutAddMenuEntry("Hidden Line", HIDDENLINE);
  841.     glutAddMenuEntry("Flat Shaded", FLATSHADED);
  842.     glutAddMenuEntry("Smooth Shaded", SMOOTHSHADED);
  843.     glutAddMenuEntry("Textured", TEXTURED);
  844.  
  845.     otherMenu = glutCreateMenu(setOther);
  846.     glutAddMenuEntry("Full Screen", FULLSCREEN);
  847.     glutAddMenuEntry("Face Normals", FACENORMALS);
  848.     glutAddMenuEntry("Antialias", ANTIALIAS);
  849.     glutAddMenuEntry("Environment Map", ENVMAP);
  850.  
  851.     speedMenu = glutCreateMenu(setSpeed);
  852.     glutAddMenuEntry("Weak", WEAK);
  853.     glutAddMenuEntry("Normal", NORMAL);
  854.     glutAddMenuEntry("Strong", STRONG);
  855.  
  856.     sizeMenu = glutCreateMenu(setSize);
  857.     glutAddMenuEntry("Small", SMALL);
  858.     glutAddMenuEntry("Medium", MEDIUM);
  859.     glutAddMenuEntry("Large", LARGE);
  860.     glutAddMenuEntry("Extra Large", XLARGE);
  861.  
  862.     resetMenu = glutCreateMenu(reset);
  863.     glutAddMenuEntry("Current", CURRENT);
  864.     glutAddMenuEntry("Spike", SPIKE);
  865.     glutAddMenuEntry("Hole", HOLE);
  866.     glutAddMenuEntry("Diagonal Wall", DIAGONALWALL);
  867.     glutAddMenuEntry("Side Wall", SIDEWALL);
  868.     glutAddMenuEntry("Middle Block", MIDDLEBLOCK);
  869.     glutAddMenuEntry("Diagonal Block", DIAGONALBLOCK);
  870.     glutAddMenuEntry("Corner Block", CORNERBLOCK);
  871.     glutAddMenuEntry("Hill", HILL);
  872.     glutAddMenuEntry("Hill Four", HILLFOUR);
  873.  
  874.     mainMenu = glutCreateMenu(setMain);
  875.     glutAddMenuEntry("Go", 2);
  876.     glutAddMenuEntry("Stop", 3);
  877.     glutAddMenuEntry("Reverse", 4);
  878.     glutAddSubMenu("Display", displayMenu);
  879.     glutAddSubMenu("Reset", resetMenu);
  880.     glutAddSubMenu("Size", sizeMenu);
  881.     glutAddSubMenu("Speed", speedMenu);
  882.     glutAddSubMenu("Other", otherMenu);
  883.     glutAddMenuEntry("Exit", 5);
  884.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  885.  
  886.     glutMainLoop();
  887. }
  888.  
  889.     
  890.